const MIN_DAY_OF_WEEK = 0; // 星期最小值 星期日
const MAX_DAY_OF_WEEK = 6; // 星期最大值 星期六
/** 星期 值 处理， 首尾循环 */
function processDayOfWeek(dayOfWeek) {
	if (dayOfWeek < MIN_DAY_OF_WEEK) {
		dayOfWeek = MAX_DAY_OF_WEEK;
	} else if (dayOfWeek > MAX_DAY_OF_WEEK) {
		dayOfWeek = MIN_DAY_OF_WEEK;
	}
	return dayOfWeek;
}
/**
 * 获取格式化时间
 * @param date 时间
 * @param format 格式
 * 将 Date 转化为指定格式的String
 * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
 * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)可以用 1-2 个占位符 
 * eg: 
 * (new Date()).pattern("yyyy-MM-dd hh:mm:ss.S")==> 2006-07-02 08:09:04.423
 * (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
 * (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
 * (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
 * (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
 */
function dateFormat(date, format = 'yyyy-MM-dd') {
	var o = {
		"M+": date.getMonth() + 1, //月份         
		"d+": date.getDate(), //日         
		"h+": date.getHours() % 12 == 0 ? 12 : date.getHours() % 12, //小时         
		"H+": date.getHours(), //小时         
		"m+": date.getMinutes(), //分         
		"s+": date.getSeconds(), //秒       
		"S": date.getMilliseconds() //毫秒         
	};
	var week = {
		"0": "日",
		"1": "一",
		"2": "二",
		"3": "三",
		"4": "四",
		"5": "五",
		"6": "六"
	};
	if (/(y+)/.test(format)) {
		format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
	}
	if (/(E+)/.test(format)) {
		format = format.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "星期" : "周") : "") + week[
			date.getDay() + ""]);
	}
	for (var k in o) {
		if (new RegExp("(" + k + ")").test(format)) {
			format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k])
				.length)));
		}
	}
	return format;
}

/**
 * 获取时间
 * @param targetDate 目标时间 可以为空 Date 类型 或者 毫秒
 * @param yearDuration 年份差距 数字类型 可以为空
 * @param monthDuration 月份差距 数字类型 可以为空
 * @param weekDuration 周差距 数字类型 可以为空
 * @param dayDuration 天差距 数字类型 可以为空
 * @param hourDuration 小时差距 数字类型 可以为空
 * @param minDuration 分钟差距 数字类型 可以为空
 * @param secDuration 秒数差距 数字类型 可以为空
 */
function getDate({
	targetDate,
	yearDuration,
	monthDuration,
	weekDuration,
	dayDuration,
	hourDuration,
	minDuration,
	secDuration
}) {
	let tempDate = new Date();
	if (targetDate != null) {
		tempDate = new Date(targetDate);
	}

	if (yearDuration != null) {
		tempDate.setFullYear(tempDate.getFullYear() * 1 + parseInt(yearDuration));
	}

	if (monthDuration != null) {
		tempDate.setMonth(tempDate.getMonth() * 1 + parseInt(monthDuration));
	}

	if (weekDuration != null) {
		tempDate.setDate(tempDate.getDate() * 1 + (7 * parseInt(weekDuration)));
	}

	if (dayDuration != null) {
		tempDate.setDate(tempDate.getDate() * 1 + parseInt(dayDuration));
	}

	if (hourDuration != null) {
		tempDate.setHours(tempDate.getHours() * 1 + parseInt(hourDuration));
	}

	if (minDuration != null) {
		tempDate.setMinutes(tempDate.getMinutes() * 1 + parseInt(minDuration));
	}

	if (secDuration != null) {
		tempDate.setSeconds(tempDate.getSeconds() * 1 + parseInt(secDuration));
	}

	return tempDate;
}
/**
 * 日期时间 string 转 date
 * @param {string} dateStr 日期时间
 */
function stringToDate(dateStr) {
	if (!dateStr) return null;
	return new Date(Date.parse(dateStr.replace(/-/g, "/")))
}

/** 获取相差分钟 */
function getMinDis(startDate, endDate) {
	let startTime = stringToDate(startDate);
	let endTime = stringToDate(endDate);
	return parseInt(Math.abs(endTime - startTime)) / 1000 / 60
}

/** 获取相差小时数 */
function getHourDis(startDate, endDate) {
	let startTime = stringToDate(startDate);
	let endTime = stringToDate(endDate);
	return parseInt(Math.abs(endTime - startTime)) / 1000 / 60 / 60
}

/** 获取天数相差多少天 */
function getDayDis(startDay, endDay) {
	let startDate = stringToDate(startDay);
	let endDate = stringToDate(endDay);
	return parseInt(Math.abs(endDate - startDate)) / 1000 / 60 / 60 / 24;
}

/** 获取日期对象 */
function getDateModel(date, fullDateFormat = 'yyyy-MM-dd') {
	return {
		date,
		time: dateFormat(date, "HH:mm"),
		fullDay: dateFormat(date, fullDateFormat),
		day: dateFormat(date, "MM.dd"),
		week: dateFormat(date, "EE"),
		weekDayIndex: date.getDay(),
	}
}

/**
 * 获取一周中的指定时间
 * @param {number} week 0~6
 * @param {string} time "hh:mm"
 * @returns 返回一周中指定星期几的时间
 */
function getAssignWeekTime(week, time) {
	let currentDate = new Date();
	let currentWeek = currentDate.getDay();
	let weekDis = week - currentWeek;
	let newDate = getDate({
		targetDate: currentDate,
		dayDuration: weekDis
	});
	let newDateStr = dateFormat(newDate, "yyyy-MM-dd");
	if (time) newDateStr = `${newDateStr} ${time}`;
	return stringToDate(newDateStr);
}

/** 获取时间描述 */
function getTimeDesc(targetTime) {
	let current = new Date();
	let target = stringToDate(targetTime);
	let distance = current.getTime() - target.getTime();
	if (distance < (1000 * 60)) {
		return `${parseInt(distance / 1000)}秒`;
	} else if (distance < (1000 * 60 * 60)) {
		return `${parseInt(distance / (1000 * 60))}分钟`
	} else if (distance < (1000 * 60 * 60 * 24)) {
		return `${parseInt(distance / (1000 * 60 * 60))}小时`
	} else {
		return `${parseInt(distance / (1000 * 60 * 60 * 24))}天`
	}
}
/** 判断当前时间 小时 是否在指定时间范围内 */
function isHourBetween(start = 0, end = 23, time = new Date()) {
	const hour = time.getHours(); // 获取当前小时（0-23）
	return hour >= start && hour < end;
}

/** 替换时间中的T */
function replaceTimeT(time) {
	return time ? time.replace("T", " ") : '';
}

module.exports = {
	processDayOfWeek,
	dateFormat,
	getDate,
	stringToDate,
	getDateModel,
	getAssignWeekTime,
	getDayDis,
	getHourDis,
	getMinDis,
	getTimeDesc,
	isHourBetween,
	replaceTimeT
}